package com.link.auth.core.config;

import com.link.auth.base.user.authority.DefaultPasswordEncoder;
import com.link.auth.base.user.authority.UserPasswordEncoder;
import com.link.auth.base.user.service.UserServiceDetail;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * webSecurity 相关配置
 * @author guoshan
 * @date 2019/12/10 17:01
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 注入用户信息，spring security oauth需要通过此bean获取用户信息
     * @author 郭闪
     * @date 2019/12/26
     * @param
     *
     */
    @Bean
    UserServiceDetail userServiceDetail() {
        return new UserServiceDetail();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //CSRF:因为不再依赖于Cookie，所以你就不需要考虑对CSRF（跨站请求伪造）的防范。
        http
                .csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint(new AuthenticationEntryPoint() {
                    @Override
                    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e)
                            throws IOException, ServletException {
                        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                    }
                })
                .and()
                .authorizeRequests()
                //对所有的请求进行认证
                .antMatchers("/**").authenticated()
                .and()
                //开启httpBasic认证
                .httpBasic();
    }

   /**
    * 不拦截actuator 相关路径
    * @author 郭闪
    * @date 2019/12/10
    * @param web
    */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/actuator/**");
    }

  /**
   * 认证管理配置：配置用户详细信息，以及密码编码实现
   * @author 郭闪
   * @date 2019/12/10
   * @param auth
   */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userServiceDetail())
                .passwordEncoder(new UserPasswordEncoder());
    }

    /**
     * 默认密码校验
     * @author  郑宏达
     * @date:   2019-04-28
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new DefaultPasswordEncoder();
    }
}
